library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

package dec_pkg is 
 -------------top pack
  subtype bank_num is integer range 0 to 7;			--memory bank list_number
  subtype block_length is integer range 50 to 512;			--max length of data blocks (frame=400, len=50)
  subtype frame_length is integer range 0 to 4096;			--max length of frame (frame=400, len=50)
 subtype word8 is std_ulogic_vector(7 downto 0);
  subtype word9 is std_ulogic_vector(8 downto 0);
  subtype word10 is std_ulogic_vector(9 downto 0);
  subtype word16 is std_ulogic_vector(15 downto 0);
  subtype word32 is std_ulogic_vector(31 downto 0);
  type word32_array is array (7 downto 0) of word32;
  type word16_array is array (7 downto 0) of word16;
  type word10_array is array (7 downto 0) of word10;
  type word9_array is array (7 downto 0) of word9;
  type word8_array is array (7 downto 0) of word8;
  subtype word_addr is std_ulogic_vector(7 downto 0);
  
  -- Convert a std_ulogic_vector to an unsigned integer
  function to_int (a: std_ulogic_vector)  return integer; 
  function CONV_STD_ULOGIC_VECTOR(ARG: INTEGER; SIZE: INTEGER) 
                                                       return STD_ULOGIC_VECTOR;

  function generator(a:integer )   return std_ulogic_vector;
 function gen(a:integer )   return std_ulogic_vector;
 function transform(c :std_ulogic_vector(15 downto 0)) return std_ulogic ;

  -- Select the right one from eight memory banks
  function sel_bank( c : std_ulogic_vector(11 downto 0);l : block_length )  return word8;

  -- output the address for specific memory bank 
  function bank_addr (c:std_ulogic_vector(11 downto 0); l:block_length;w:word8) return word_addr;
    function sig_value(sel:word16) return word16;  







----------------------------cup pack

	  type matrix_integer_23 is array (-11 to 11) of integer range 0 to 12;
	  
	  type matrix_8_4 is array (1 to 8) of std_ulogic_vector(3 downto 0);
	  type matrix_8_16 is array (1 to 8) of std_ulogic_vector(15 downto 0);
	  
	  type matrix_23_19 is array (0 to 22) of std_ulogic_vector(18 downto 0);
	  
	  type matrix_23_20 is array (0 to 22) of std_ulogic_vector(19 downto 0);
	  type matrix_23_23 is array (0 to 22) of std_ulogic_vector(22 downto 0);

	  type matrix_23_21 is array (0 to 22) of std_ulogic_vector(20 downto 0);
	  type matrix_23_24 is array (0 to 22) of std_ulogic_vector(23 downto 0);

	  type matrix_23_40 is array (0 to 22) of std_ulogic_vector(39 downto 0);
	  
	  type matrix_23_30 is array (0 to 22) of std_ulogic_vector(29 downto 0);
	  type matrix_u_23_30 is array (0 to 22) of std_ulogic_vector(29 downto 0);
	  
	  type matrix_29_21 is array (0 to 28) of std_ulogic_vector(20 downto 0);
	  type matrix_29_24 is array (0 to 28) of std_ulogic_vector(23 downto 0);
	  
	  type matrix_12_19 is array (0 to 11) of std_ulogic_vector(18 downto 0);
	  type matrix_23_12_19 is array (-11 to 11) of matrix_12_19;
	  
	  type matrix_10_19 is array (0 to 9) of std_ulogic_vector(18 downto 0);
	  type matrix_23_10_19 is array (-11 to 11) of matrix_10_19;
	  
	  ---------------------------consult table-----------------------------
	  
	  function maximum(L, R: INTEGER) return INTEGER;
	  function usxt(ARG: std_ulogic_vector; SIZE: integer) return std_ulogic_vector; 
	  function max2 (din1,din2: std_ulogic_vector(18 downto 0)) return std_ulogic_vector;
	  function max2_24(din1,din2: std_ulogic_vector(23 downto 0)) return std_ulogic_vector;
	  function "+" (L: std_ulogic_vector; R: std_ulogic_vector) return std_ulogic_vector;
	  function "-" (L: std_ulogic_vector; R: std_ulogic_vector) return std_ulogic_vector;
	  function "*"(L: STD_uLOGIC_VECTOR; R: STD_uLOGIC_VECTOR) return STD_uLOGIC_VECTOR;
	  function consult_pos  (p:std_ulogic_vector(15 downto 0)) return STD_ULOGIC_VECTOR;
	  function consult_tab1 (p:std_ulogic_vector(5 downto 0)) return std_ulogic_vector;
	  function consult_tab2 (p:std_ulogic_vector(5 downto 0)) return std_ulogic_vector;












end dec_pkg;

package body dec_pkg is
 ----------------------top pack
   function generator(a :integer ) return std_ulogic_vector is
	  variable temp :std_ulogic_vector(7 downto 0);
	 begin 
	    for i in 0 to 7 loop
		     if (i = a)  then 
			     temp(i) := '1' ;
				  else 
				  temp(i) := '0';
				  end if;
				  end loop;
				  
	 return temp;
	end generator ;
  
   function gen(a :integer ) return std_ulogic_vector is
	  variable temp :std_ulogic_vector(127 downto 0);
	 begin 
	    for i in 0 to 127 loop
		     if (i = a)  then 
			     temp(i) := '1' ;
				  else 
				  temp(i) := '0';
				  end if;
				  end loop;
				  
	 return temp;
	end gen ;
    -- Convert a std_ulogic_vector to an unsigned integer
    function to_int (a: std_ulogic_vector) return integer is
        alias av: std_ulogic_vector (1 to a'length) is a;
        variable val: integer := 0;
        variable b: integer := 1;
    begin
        for i in a'length downto 1 loop
            if (av(i) = '1') then     -- if LSB is '1',
                val := val + b;       -- add value for current bit position
            end if;
            b := b * 2;    -- Shift left 1 bit
        end loop;
        return val;
    end to_int;
	
	
	-- convert an integer to an STD_LOGIC_VECTOR
    function CONV_STD_ULOGIC_VECTOR(ARG: INTEGER; SIZE: INTEGER) return STD_ULOGIC_VECTOR is
        variable result: STD_ULOGIC_VECTOR (SIZE-1 downto 0);
        variable temp: integer;
        -- synopsys built_in SYN_INTEGER_TO_BIT_VECTOR
        -- synopsys subpgm_id 381
    begin
        -- synopsys synthesis_off
        temp := ARG;
        for i in 0 to SIZE-1 loop
            if (temp mod 2) = 1 then
                result(i) := '1';
            else 
                result(i) := '0';
            end if;
            if temp > 0 then
                temp := temp / 2;
            elsif (temp > integer'low) then
                temp := (temp - 1) / 2; -- simulate ASR
            else
                temp := temp / 2; -- simulate ASR
            end if;
        end loop;
        return result;
        -- synopsys synthesis_on
    end;
      

    function sel_bank ( c : std_ulogic_vector(11 downto 0);l : block_length)  return word8 is
       variable n : word8;
       variable val : integer;
    begin
	  val := to_int(c);
	  if val = 8 * l then 
	     n  := (others => '0');
 	  elsif   val < l 		then
	      n  := "00000001";
 	  elsif  val < l*2 	then
		    n := "00000010";
	  elsif	 val < l*3	then
	       n := "00000100";
    elsif  val < l*4	then
      		n := "00001000";
	  elsif  val < l*5	then
       	n := "00010000";
	  elsif  val < l*6	then
 		    n := "00100000";
	  elsif  val < l*7	then
		    n := "01000000";
	  else
  		    n := "10000000";
	  end if;		
	 return n;
  end sel_bank;
  

    function bank_addr (c: std_ulogic_vector(11 downto 0); l:block_length ;w : word8) return word_addr	is
	variable n : integer;
   variable addr: integer;
   variable t : std_ulogic_vector(31 downto 0);
    begin
	       n := to_int(c);
	      if w(0) = '1' then 
	        addr :=  n;
	      elsif w(1) = '1' then
	        addr :=  n - l;
	      elsif w(2) = '1' then 
	        addr := n - 2 * l;
	      elsif w(3) = '1' then 
	        addr := n - 3 * l;
	      elsif w(4) = '1' then 
	        addr := n - 4 * l;
	      elsif w(5) = '1' then 
	        addr := n - 5 * l ;
	      elsif w(6) = '1' then 
	        addr := n - 6 * l;
	      elsif w(7) = '1' then 
	        addr := n - 7 *l;
	      else
	        addr := 0;
	      end if;   
	       t := conv_std_ulogic_vector(addr , 32);          
	return t(7 downto 0);
 end bank_addr;  
    
    
    function transform(c :std_ulogic_vector(15 downto 0)) return std_ulogic is
    variable b : std_ulogic;
    begin
      if c(15) = '0' then 
        if c(14 downto 0) = "000000000000000" then
             b := '0' ;
           else 
             b := '1';
          end if;
        else 
          b := '0';
        end  if;
        return b;
          end transform;

      function sig_value(sel:word16) return word16 is
       variable pos : std_ulogic_vector(6 downto 0);
       variable sigmalis : word16;
    begin
	pos :=conv_std_ulogic_vector((to_int(sel(11 downto 5))-1),7);
	case pos is
	when	 "0000000" => sigmalis := "0111111111111111";
	when	 "0000001" => sigmalis := "0100000000000000";
	when	 "0000010" => sigmalis := "0001110001110001";
	when	 "0000011" => sigmalis := "0001000000000000";
	when	 "0000100" => sigmalis := "0000101000111101";
	when	 "0000101" => sigmalis := "0000011100011100";
	when	 "0000110" => sigmalis := "0000010100111001";
	when	 "0000111" => sigmalis := "0000010000000000";
	when	 "0001000" => sigmalis := "0000001100101001";
	when	 "0001001" => sigmalis := "0000001010001111";
	when	 "0001010" => sigmalis := "0000001000011101";
	when	 "0001011" => sigmalis := "0000000111000111";
	when	 "0001100" => sigmalis := "0000000110000011";
	when	 "0001101" => sigmalis := "0000000101001110";
	when	 "0001110" => sigmalis := "0000000100100011";
	when	 "0001111" => sigmalis := "0000000100000000";
	when	 "0010000" => sigmalis := "0000000011100010";
	when	 "0010001" => sigmalis := "0000000011001010";
	when	 "0010010" => sigmalis := "0000000010110101";
	when	 "0010011" => sigmalis := "0000000010100011";
	when	 "0010100" => sigmalis := "0000000010010100";
	when	 "0010101" => sigmalis := "0000000010000111";
	when	 "0010110" => sigmalis := "0000000001111011";
	when	 "0010111" => sigmalis := "0000000001110001";
	when	 "0011000" => sigmalis := "0000000001101000";
	when	 "0011001" => sigmalis := "0000000001100000";
	when	 "0011010" => sigmalis := "0000000001011001";
	when	 "0011011" => sigmalis := "0000000001010011";
	when	 "0011100" => sigmalis := "0000000001001101";
	when	 "0011101" => sigmalis := "0000000001001000";
	when	 "0011110" => sigmalis := "0000000001000100";
	when	 "0011111" => sigmalis := "0000000001000000";
	when	 "0100000" => sigmalis := "0000000000111100";
	when	 "0100001" => sigmalis := "0000000000111000";
	when	 "0100010" => sigmalis := "0000000000110101";
	when	 "0100011" => sigmalis := "0000000000110010";
	when	 "0100100" => sigmalis := "0000000000101111";
	when	 "0100101" => sigmalis := "0000000000101101";
	when	 "0100110" => sigmalis := "0000000000101011";
	when	 "0100111" => sigmalis := "0000000000101000";
	when	 "0101000" => sigmalis := "0000000000100110";
	when	 "0101001" => sigmalis := "0000000000100101";
	when	 "0101010" => sigmalis := "0000000000100011";
	when	 "0101011" => sigmalis := "0000000000100001";
	when	 "0101100" => sigmalis := "0000000000100000";
	when	 "0101101" => sigmalis := "0000000000011110";
	when	 "0101110" => sigmalis := "0000000000011101";
	when	 "0101111" => sigmalis := "0000000000011100";
	when	 "0110000" => sigmalis := "0000000000011011";	
	when	 "0110001" => sigmalis := "0000000000011010";
	when	 "0110010" => sigmalis := "0000000000011001";
	when	 "0110011" => sigmalis := "0000000000011000";
	when	 "0110100" => sigmalis := "0000000000010111";
	when	 "0110101" => sigmalis := "0000000000010110";
	when	 "0110110" => sigmalis := "0000000000010101";
	when	 "0110111" => sigmalis := "0000000000010100";
	when	 "0111000" => sigmalis := "0000000000010100";
	when	 "0111001" => sigmalis := "0000000000010011";	
	when	 "0111010" => sigmalis := "0000000000010010";
	when	 "0111011" => sigmalis := "0000000000010010";
	when	 "0111100" => sigmalis := "0000000000010001";
	when	 "0111101" => sigmalis := "0000000000010001";
	when	 "0111110" => sigmalis := "0000000000010000";
	when	 "0111111" => sigmalis := "0000000000010000";
	when	 "1000000" => sigmalis := "0000000000001111";
	when	 "1000001" => sigmalis := "0000000000001111";
	when	 "1000010" => sigmalis := "0000000000001110";
	when	 "1000011" => sigmalis := "0000000000001110";
	when	 "1000100" => sigmalis := "0000000000001101";
	when	 "1000101" => sigmalis := "0000000000001101";	
	when	 "1000110" => sigmalis := "0000000000001101";
	when	 "1000111" => sigmalis := "0000000000001100";
	when	 "1001000" => sigmalis := "0000000000001100";
	when	 "1001001" => sigmalis := "0000000000001011";
	when	 "1001010" => sigmalis := "0000000000001011";
	when	 "1001011" => sigmalis := "0000000000001011";
	when	 "1001100" => sigmalis := "0000000000001011";
	when	 "1001101" => sigmalis := "0000000000001010";
	when	 "1001110" => sigmalis := "0000000000001010";
	when	 "1001111" => sigmalis := "0000000000001010";
	when	 "1010000" => sigmalis := "0000000000001001";
	when	 "1010001" => sigmalis := "0000000000001001";
	when	 "1010010" => sigmalis := "0000000000001001";
	when	 "1010011" => sigmalis := "0000000000001001";
	when	 "1010100" => sigmalis := "0000000000001001";
	when	 "1010101" => sigmalis := "0000000000001000";
	when	 "1010110" => sigmalis := "0000000000001000";
	when	 "1010111" => sigmalis := "0000000000001000";
	when	 "1011000" => sigmalis := "0000000000001000";
	when	 "1011001" => sigmalis := "0000000000001000";
	when	 "1011010" => sigmalis := "0000000000000111";
	when	 "1011011" => sigmalis := "0000000000000111";
	when	 "1011100" => sigmalis := "0000000000000111";
	when	 "1011101" => sigmalis := "0000000000000111";
	when	 "1011110" => sigmalis := "0000000000000111";
	when	 "1011111" => sigmalis := "0000000000000111";
	when	 "1100000" => sigmalis := "0000000000000110";
	when	 "1100001" => sigmalis := "0000000000000110";
	when	 "1100010" => sigmalis := "0000000000000110";
	when	 "1100011" => sigmalis := "0000000000000110";
	when	 "1100100" => sigmalis := "0000000000000110";
	when	 "1100101" => sigmalis := "0000000000000110";
	when	 "1100110" => sigmalis := "0000000000000110";
	when	 "1100111" => sigmalis := "0000000000000110";	
	when	 "1101000" => sigmalis := "0000000000000101";
	when	 "1101001" => sigmalis := "0000000000000101";
	when	 "1101010" => sigmalis := "0000000000000101";
	when	 "1101011" => sigmalis := "0000000000000101";
	when	 "1101100" => sigmalis := "0000000000000101";
	when	 "1101101" => sigmalis := "0000000000000101";
	when	 "1101110" => sigmalis := "0000000000000101";
	when	 "1101111" => sigmalis := "0000000000000101";
	when	 "1110000" => sigmalis := "0000000000000101";
	when	 "1110001" => sigmalis := "0000000000000101";
	when	 "1110010" => sigmalis := "0000000000000100";
	when	 "1110011" => sigmalis := "0000000000000100";
	when	 "1110100" => sigmalis := "0000000000000100";
	when	 "1110101" => sigmalis := "0000000000000100";
	when	 "1110110" => sigmalis := "0000000000000100";
	when	 "1110111" => sigmalis := "0000000000000100";
	when	 "1111000" => sigmalis := "0000000000000100";
	when	 "1111001" => sigmalis := "0000000000000100";
	when	 "1111010" => sigmalis := "0000000000000100";
	when	 "1111011" => sigmalis := "0000000000000100";
	when	 "1111100" => sigmalis := "0000000000000100";
	when	 "1111101" => sigmalis := "0000000000000100";
	when	 "1111110" => sigmalis := "0000000000000100";
	when	 "1111111" => sigmalis := "0000000000000100";
	when others=>null;
        end case;
	return sigmalis;
    end sig_value;
    
-------------------cup pack 
   function consult_pos (p:std_ulogic_vector(15 downto 0)) return std_ulogic_vector is 
	    variable p_1,delt: std_ulogic_vector(15 downto 0);
       variable pos1: std_ulogic_vector(5 downto 0);
	begin
	p_1:=p;
	if p_1(15)='0' then
		if to_stdlogicvector(p_1)>"0001000000000000"  then
			pos1 := "111111";
		elsif p_1="0000000000000000"  then
			pos1 :="000000";
		else
			pos1 :=p_1(11 downto 6);
		end if;
		delt := consult_tab1(pos1)+p_1;
	else
		p_1:=(not p_1)+"01";
		 if to_stdlogicvector(p_1)>="0001000000000000" then
			pos1 :="111111";
		else 
			pos1 :=p_1(11 downto 6);
		end if;
		delt := consult_tab2(pos1);
	end if;
	return delt;
	end function;


	function consult_tab1 (p:std_ulogic_vector(5 downto 0)) return std_ulogic_vector is
		variable d :std_ulogic_vector(15 downto 0);
	begin
	case p is
when	 "000000" => d := "0000000101100010";
when	 "000001" => d := "0000000101000011";
when	 "000010" => d := "0000000100100110";
when	 "000011" => d := "0000000100001011";
when	 "000100" => d := "0000000011110010";
when	 "000101" => d := "0000000011011011";
when	 "000110" => d := "0000000011000110";
when	 "000111" => d := "0000000010110010";
when	 "001000" => d := "0000000010100000";
when	 "001001" => d := "0000000010001111";
when	 "001010" => d := "0000000010000000";
when	 "001011" => d := "0000000001110011";
when	 "001100" => d := "0000000001100111";
when	 "001101" => d := "0000000001011100";
when	 "001110" => d := "0000000001010010";
when	 "001111" => d := "0000000001001001";
when	 "010000" => d := "0000000001000000";
when	 "010001" => d := "0000000000111001";
when	 "010010" => d := "0000000000110011";
when	 "010011" => d := "0000000000101101";
when	 "010100" => d := "0000000000101000";
when	 "010101" => d := "0000000000100011";
when	 "010110" => d := "0000000000011111";
when	 "010111" => d := "0000000000011100";
when	 "011000" => d := "0000000000011000";
when	 "011001" => d := "0000000000010110";
when	 "011010" => d := "0000000000010011";
when	 "011011" => d := "0000000000010001";
when	 "011100" => d := "0000000000001111";
when	 "011101" => d := "0000000000001101";
when	 "011110" => d := "0000000000001011";
when	 "011111" => d := "0000000000001010";
when	 "100000" => d := "0000000000001001";
when	 "100001" => d := "0000000000001000";
when	 "100010" => d := "0000000000000111";
when	 "100011" => d := "0000000000000110";
when	 "100100" => d := "0000000000000101";
when	 "100101" => d := "0000000000000100";
when	 "100110" => d := "0000000000000100";
when	 "100111" => d := "0000000000000011";
when	 "101000" => d := "0000000000000011";
when	 "101001" => d := "0000000000000011";
when	 "101010" => d := "0000000000000010";
when	 "101011" => d := "0000000000000010";
when	 "101100" => d := "0000000000000010";
when	 "101101" => d := "0000000000000001";
when	 "101110" => d := "0000000000000001";
when	 "101111" => d := "0000000000000001";
when	 "110000" => d := "0000000000000001";
when	 "110001" => d := "0000000000000001";
when	 "110010" => d := "0000000000000000";
when	 "110011" => d := "0000000000000000";
when	 "110100" => d := "0000000000000000";
when	 "110101" => d := "0000000000000000";
when	 "110110" => d := "0000000000000000";
when	 "110111" => d := "0000000000000000";
when	 "111000" => d := "0000000000000000";
when	 "111001" => d := "0000000000000000";
when	 "111010" => d := "0000000000000000";
when	 "111011" => d := "0000000000000000";
when	 "111100" => d := "0000000000000000";
when	 "111101" => d := "0000000000000000";
when	 "111110" => d := "0000000000000000";
when	 "111111" => d := "0000000000000000";
when others=>null;
end case;
	
	return d;
	
end function;
	
	
	function consult_tab2 (p:std_ulogic_vector(5 downto 0)) return std_ulogic_vector is
		variable d :std_ulogic_vector(15 downto 0);
	begin
	case p is
when	 "000000" => d := "0000000101000011";
when	 "000001" => d := "0000000100100110";
when	 "000010" => d := "0000000100001011";
when	 "000011" => d := "0000000011110010";
when	 "000100" => d := "0000000011011011";
when	 "000101" => d := "0000000011000110";
when	 "000110" => d := "0000000010110010";
when	 "000111" => d := "0000000010100000";
when	 "001000" => d := "0000000010001111";
when	 "001001" => d := "0000000010000000";
when	 "001010" => d := "0000000001110011";
when	 "001011" => d := "0000000001100111";
when	 "001100" => d := "0000000001011100";
when	 "001101" => d := "0000000001010010";
when	 "001110" => d := "0000000001001001";
when	 "001111" => d := "0000000001000000";
when	 "010000" => d := "0000000000111001";
when	 "010001" => d := "0000000000110011";
when	 "010010" => d := "0000000000101101";
when	 "010011" => d := "0000000000101000";
when	 "010100" => d := "0000000000100011";
when	 "010101" => d := "0000000000011111";
when	 "010110" => d := "0000000000011100";
when	 "010111" => d := "0000000000011000";
when	 "011000" => d := "0000000000010110";
when	 "011001" => d := "0000000000010011";
when	 "011010" => d := "0000000000010001";
when	 "011011" => d := "0000000000001111";
when	 "011100" => d := "0000000000001101";
when	 "011101" => d := "0000000000001011";
when	 "011110" => d := "0000000000001010";
when	 "011111" => d := "0000000000001001";
when	 "100000" => d := "0000000000001000";
when	 "100001" => d := "0000000000000111";
when	 "100010" => d := "0000000000000110";
when	 "100011" => d := "0000000000000101";
when	 "100100" => d := "0000000000000100";
when	 "100101" => d := "0000000000000100";
when	 "100110" => d := "0000000000000011";
when	 "100111" => d := "0000000000000011";
when	 "101000" => d := "0000000000000011";
when	 "101001" => d := "0000000000000010";
when	 "101010" => d := "0000000000000010";
when	 "101011" => d := "0000000000000010";
when	 "101100" => d := "0000000000000001";
when	 "101101" => d := "0000000000000001";
when	 "101110" => d := "0000000000000001";
when	 "101111" => d := "0000000000000001";
when	 "110000" => d := "0000000000000001";
when	 "110001" => d := "0000000000000000";
when	 "110010" => d := "0000000000000000";
when	 "110011" => d := "0000000000000000";
when	 "110100" => d := "0000000000000000";
when	 "110101" => d := "0000000000000000";
when	 "110110" => d := "0000000000000000";
when	 "110111" => d := "0000000000000000";
when	 "111000" => d := "0000000000000000";
when	 "111001" => d := "0000000000000000";
when	 "111010" => d := "0000000000000000";
when	 "111011" => d := "0000000000000000";
when	 "111100" => d := "0000000000000000";
when	 "111101" => d := "0000000000000000";
when	 "111110" => d := "0000000000000000";
when	 "111111" => d := "0000000000000000";
when others=>null;
end case;

return d;
	
end function;
		function maximum(L, R: INTEGER) return INTEGER is
    begin
        if L > R then
            return L;
        else
            return R;
        end if;
    end;

		
		    function "*"(L: STD_uLOGIC_VECTOR; R: STD_uLOGIC_VECTOR) return STD_uLOGIC_VECTOR is
            -- pragma label_applies_to mult
            constant length: INTEGER := maximum(L'length, R'length);
            variable result  : signed ((L'length+R'length-1) downto 0);
        begin
            result  := SIGNED(L) * SIGNED(R); -- pragma label mult
            return   std_ulogic_vector(result);
        end;
    
    function USXT(ARG: STD_ULOGIC_VECTOR; SIZE: INTEGER) return STD_ULOGIC_VECTOR is
   variable len: INTEGER RANGE 0 TO 31;
   variable temp: STD_ULOGIC_VECTOR(SIZE-1 DOWNTO 0);
begin
   if ARG'length >= SIZE then
     return ARG(SIZE-1 downto 0);
   else
     len := SIZE - ARG'length;
     temp(SIZE-1 DOWNTO SIZE-len) := (others=>ARG(ARG'length-1));
     temp(SIZE-len-1 DOWNTO 0) := ARG;
     return temp;
   end if;
end;


function "+"(L: std_ulogic_vector; R: std_ulogic_vector) return STD_ULOGIC_VECTOR is
	variable temp: unsigned(L'length-1 downto 0);
begin
  temp := unsigned(L)+unsigned(R);
	return std_ulogic_vector(temp);
end;


function "-"(L: std_ulogic_vector; R: std_ulogic_vector) return STD_ULOGIC_VECTOR is
	variable temp: unsigned(L'length-1 downto 0);
begin
  temp := unsigned(L)-unsigned(R);
	return std_ulogic_vector(temp);
end;


--function max2 (din1,din2: std_ulogic_vector(18 downto 0)) return std_ulogic_vector  is
--   --variable temp:unsigned(18 downto 0);
--  begin
--	    --temp:=unsigned(din1)-unsigned(din2);
--	    --if temp(18)='1' then
--	    if unsigned(din1)<unsigned(din2) then
--      return din2;
--	    else 
--	    return din1;
--	    end if;
--end;

--function max2_21 (din1,din2: std_ulogic_vector(20 downto 0)) return std_ulogic_vector  is
   --variable temp:unsigned(20 downto 0);
 -- begin
	    --temp:=unsigned(din1)-unsigned(din2);
	    --if temp(20)='1' then
--	    if unsigned(din1)<unsigned(din2)  then
 --     return din2;
	   -- else 
	   -- return din1;
	   -- end if;
--end;

function max2 (din1,din2: std_ulogic_vector(18 downto 0)) return std_ulogic_vector  is
  begin
	    if din1(18)='0' and din2(18)='0'  then
	      if din1<din2 then
	        return din2;
	        else 
	          return din1;
	          end if;
      elsif din1(18)='1' and din2(18)='1'  then
        if din1<din2 then
           return din2;
        else
           return din1;
        end if;
        elsif din1(18)='0' and din2(18)='1'  then
          return din1;
        else
            return din2;
        end if;
end;

function max2_24 (din1,din2: std_ulogic_vector(23 downto 0)) return std_ulogic_vector  is
  begin
	    if din1(23)='0' and din2(23)='0'  then
	      if din1<din2 then
	        return din2;
	        else 
	          return din1;
	          end if;
      elsif din1(23)='1' and din2(23)='1'  then
        if din1<din2 then
           return din2;
        else
           return din1;
        end if;
        elsif din1(23)='0' and din2(23)='1'  then
          return din1;
        else
            return din2;
        end if;
end; 
end dec_pkg;
